package com.wuster.controller;

import com.wuster.entity.Admin;
import com.wuster.entity.AdminVO;
import com.wuster.entity.dto.AdminDTO;
import com.wuster.entity.dto.PassWordDTO;
import com.wuster.result.Result;
import com.wuster.result.ResultCodeEnum;
import com.wuster.service.AdminService;
import com.wuster.utils.JwtUtil;
import com.wuster.utils.Md5Util;
import com.wuster.utils.ThreadLocalUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequestMapping("/account")
@Api(tags="管理员相关接口")
public class AdminController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //没用了
    //用于最开始插入一个管理员账户信息,同时加密密码
//    @GetMapping("/register")
//    public Result register(){
//        Admin admin = new Admin();
//        admin.setName("admin");
//        admin.setPassword(Md5Util.getMD5String("123456"));
//        //java实体类的时间类型与数据库的时间类型可能有冲突
//        Date date = new Date();
//        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//        admin.setCreateTime(Timestamp.valueOf(dateFormat.format(date)));
//        admin.setUpdateTime(Timestamp.valueOf(dateFormat.format(date)));
//        adminService.save(admin);
//        return Result.success("后端插入一个管理员成功");
//    }


    //管理员登录
    @PostMapping("/login")
    @ApiOperation("管理员登录")
    public Result adminLogin(@RequestBody AdminDTO adminDTO){
        String adminName = adminDTO.getAdminName();
        String passWord = adminDTO.getPassWord();
        if(adminName == null || adminName.length()==0){
            return Result.error(ResultCodeEnum.USERNAME_IS_NOT_NULL.getCode(),ResultCodeEnum.USERNAME_IS_NOT_NULL.getMessage());
        }
        if(passWord == null || passWord.length()==0){
            return Result.error(ResultCodeEnum.PASSWORD_IS_NOT_NULL.getCode(), ResultCodeEnum.PASSWORD_IS_NOT_NULL.getMessage());
        }
        Admin admin = adminService.selectAdminByName(adminName);
        System.out.println("管理员是"+adminName);
        //判断管理员是否为空,空则找不到此管理员,返回管理员名错误的信息
        if (admin==null){
            log.info("管理员登录名错误");
            return Result.error(ResultCodeEnum.USERNAME_NOT_EXIST.getCode(), ResultCodeEnum.USERNAME_NOT_EXIST.getMessage());
        }
        //判断密码是否正确
        //生成Token存储
        //MD5算法加密
        if(Md5Util.getMD5String(passWord).equals(admin.getPassword())){
            //登录成功
            Map<String,Object> claims=new HashMap<>();
            claims.put("id",admin.getId());
            claims.put("adminName",admin.getName());
            String token = JwtUtil.genToken(claims);
            //把令牌存储到Redis中
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(token,token,2, TimeUnit.HOURS);
            AdminVO adminVO=AdminVO.builder()
                    .id(admin.getId())
                    .adminName(admin.getName())
                    .token(token)
                    .build();
            log.info("管理员{}登录成功",adminName);
            return Result.success(adminVO);
        }
        log.info("管理员{}输入密码错误:",adminName);
        //密码不对则返回密码错误
        return Result.error(ResultCodeEnum.PASSWORD_ERROR.getCode(), ResultCodeEnum.PASSWORD_ERROR.getMessage());
    }


    //管理员修改密码
    @PostMapping("/setPassword")
    @ApiOperation("管理员修改密码")
    public Result setPassword(@RequestBody PassWordDTO passWordDTO){
        String newPassword = passWordDTO.getNewPassword();
        String oldPassword = passWordDTO.getOldPassword();
        if(oldPassword == null || oldPassword.length()==0){
            return Result.error(ResultCodeEnum.OLDPASSWORD_IS_NOT_NULL.getCode(), ResultCodeEnum.OLDPASSWORD_IS_NOT_NULL.getMessage());
        }
        if(newPassword == null || newPassword.length()==0){
            return Result.error(ResultCodeEnum.NEWPASSWORD_LENGTH_IS_NOT_NULL.getCode(), ResultCodeEnum.NEWPASSWORD_LENGTH_IS_NOT_NULL.getMessage());
        }
        if(newPassword.length()<5){
            return Result.error(ResultCodeEnum.NEWPASSWORD_LENGTH_SHORT.getCode(), ResultCodeEnum.NEWPASSWORD_LENGTH_SHORT.getMessage());
        }else if(newPassword.length()>10){
            return Result.error(ResultCodeEnum.NEWPASSWORD_LENGTH_LONG.getCode(), ResultCodeEnum.NEWPASSWORD_LENGTH_LONG.getMessage());
        }
        //新旧密码格式和相等由前端进行验证
        //从ThreadLocal中取出管理员名
        Map<String,Object>map  = ThreadLocalUtil.get();
        String adminName = (String)map.get("adminName");
        //查出管理员的信息
        Admin admin = adminService.selectAdminByName(adminName);
        //查询旧密码,核实旧密码,不对返回旧密码错误的信息
        if(!Md5Util.getMD5String(oldPassword).equals(admin.getPassword())){
            log.info("管理员{}设置密码错误",adminName);
            return Result.error(ResultCodeEnum.OLDPASSWORD_ERRPR.getCode(), ResultCodeEnum.OLDPASSWORD_ERRPR.getMessage());
        }
        //旧密码正确,更新密码,返回修改密码成功的信息
        adminService.updateAdminPassword(adminName,Md5Util.getMD5String(newPassword));
        log.info("管理员{}设置密码成功",adminName);
        return Result.success();
    }


    //管理员登出
    @GetMapping("/logout")
    @ApiOperation("管理员退出系统")
    public Result logout(@RequestHeader(value = "Authorization") String token){
        //从缓存中清除token,返回一个管理员id
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String redisToken = operations.get(token);
        if(redisToken==null){
            return Result.error(ResultCodeEnum.LOGOUT_ERROR.getCode(), ResultCodeEnum.LOGOUT_ERROR.getMessage());
        }else if(redisToken.equals(token)){
            stringRedisTemplate.delete(token);
        }
        Map<String,Object>map  = ThreadLocalUtil.get();
//        map.get("id");
//        Long id = (Long)map.get("id");
        System.out.println(map.get("id"));
        log.info("id为{}的管理员登出",map.get("id"));
        return Result.success(map.get("id"));
        //前端清除token数据,页面跳转回登录页面
    }

}